iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
AI Engineering

從 LLM 到 Harness: 打造隱私與可信任的繁中進階 OCR Agent系列 第 9 篇

Day 9 - 為什麼選 Gemma 4:26B MoE vs 31B Dense 架構差異

  • 分享至 

  • xImage
  •  

繁中的難點攤開之後,總要有一顆模型去承擔它們

所以今天回到最基本、也最容易被跳過的那一題:選型

而我要先講一句可能有點掃興的話——這一題在我這台機器上,有一半是硬體幫我選完的 😅


先講結論,免得你看到一半跑掉

三行講完:

  1. 我實際在跑的是 gemma-4-26b,MoE(Mixture of Experts,混合專家)架構,總參數 25.2B、每個 token 活躍 3.8B
  2. 選它不是因為它最準,是因為在 273 GB/s 的記憶體頻寬底下,它是「大到夠用、又不會慢到不能用」的那一個
  3. 31B Dense(稠密)版本我沒有丟掉,我把它放到候選席上——它要不要上場,由明天的實測決定

今天這篇要做的事,就是把第 2 點那句「慢到不能用」拆開給你看:慢多少、為什麼慢、以及為什麼這個「慢」不是調參能救的。

💡Tip: 如果你只想帶走一句話,是這句:在記憶體頻寬受限的機器上,決定 decode 速度的不是總參數,是活躍參數;而決定你裝不裝得下的,才是總參數。 這兩個數字被寫在同一個模型名字裡,很多人(包括我)第一次看到的時候會搞混。


MoE 的名字裡藏了兩個參數量

你如果去看 MoE 模型的命名,常常會看到兩個數字黏在一起。我這顆的標記方式是 26B-A4B:

  • 前面那個 26B 指的是總參數(實際 25.2B,取整叫 26B)
  • 後面那個 A4B 的 A 是 Activated,指每個 token 實際活躍的參數(實際 3.8B,取整叫 4B)

Dense 模型沒有這個困擾,因為它只有一個數字——總參數等於活躍參數。31B Dense 就是 31B 全部都活躍。

這兩個數字分別回答不同的問題:

你在問的問題 要看哪個參數量
這顆模型裝不裝得下我的記憶體? 總參數
它吐一個 token 要多久? 活躍參數
它「懂」多少東西? 偏向總參數,但不是線性關係(這條是通則,我沒有量化證據)

搞清楚這張表,後面的算術就只是套公式而已。


Dense 在幹嘛:每個字都把整本書翻一遍

Dense 架構是最直覺的那一種:模型有多少參數,每吐一個 token 就要把那些參數全部讀一次。

用比喻講的話,Dense 像是一個人回答每一個問題之前,都要把整本百科全書從第一頁翻到最後一頁。不管你問的是化學還是會計,流程一模一樣。

這件事在算力充足、頻寬也充足的機器上不是問題。但在我這台上,它是全部的問題——因為 Day 3 已經算過,decode 階段是 memory-bound(記憶體頻寬受限),瓶頸不在「算」,在「搬」。

Dense 的代價是:每個 token 都要把整組權重從記憶體搬到計算單元一次。


MoE 在幹嘛:翻書之前先查目錄

MoE 的想法很簡單:把模型裡最肥的那一層(FFN,前饋網路)切成很多份,每份叫一個 expert(專家),然後加一個 router(路由器)負責決定「這個 token 該送去哪幾個 expert」。

於是每個 token 只會經過被選中的那幾個 expert,其他的 expert 這一輪就整個跳過。

回到剛剛那個比喻:MoE 像是先看一眼目錄,決定這題屬於化學,然後只翻化學那幾章。

它省下來的是「搬權重」的量,不是「這本書有多厚」。 書還是整本放在桌上。

三個容易被誤解的細節

這裡有三件事我想特別標出來,因為它們直接影響後面的換算:

① attention 層通常還是 dense 的

被切成 expert 的一般是 FFN 層。attention 相關的權重每個 token 都還是要全讀。所以「活躍參數 3.8B」這個數字本身,已經包含了那些每次都要讀的 dense 部分。

② router 本身也要算,而且每一步都要算

它不是免費的。雖然 router 相對整個模型很小,但它是 decode 迴圈裡的固定開銷。

③ 記憶體佔用不會因為稀疏而變小

這條最重要。MoE 的 25.2B 參數必須全部常駐在記憶體裡,因為 router 隨時可能點到任何一個 expert。你不會知道下一個 token 要用哪幾個。

換成一句話:

MoE 省的是頻寬,不是容量。

我一開始以為 MoE 是「用 25.2B 的品質,吃 3.8B 的記憶體」,結果是「用 25.2B 的記憶體,吃 3.8B 的頻寬」。差很多。

這個誤解有一個很具體的後果:如果你的機器記憶體很緊,MoE 幫不到你。 它要求你先裝得下全部,才給你速度的折扣。在 128GB 統一記憶體上這不是問題,但如果你是 24GB 的消費級顯卡想跑一顆 MoE,你要先過的關卡跟 Dense 完全一樣。


兩種架構的正面對照

把上面講的東西整理成一張表:

維度 Dense MoE
每個 token 讀取的權重量 全部參數 只讀被選中的 expert + dense 的部分
記憶體常駐量 = 總參數 = 總參數(一樣,不打折)
decode 速度上限 被總參數壓住 被活躍參數壓住
同樣「總參數」下的品質 通常較好 通常略遜(通則,我沒有一手比較數據)
同樣「活躍參數」下的品質 通常較差 通常較好(同上,通則)
推論框架支援複雜度 低 高(MoE backend、kernel 要對得上量化格式)
最適合的硬體 頻寬充足(HBM 等級) 頻寬受限(LPDDR5X 這種)

倒數第二行我特別想提一下,因為 Day 4 已經被咬過一次:MoE 多了一個「backend 要對得上 checkpoint 量化格式」的失敗面。FlashInfer 的 MXFP4 MoE backend 餵 NVFP4 checkpoint 進去不會報錯,會吐亂碼。Dense 模型沒有這一層地雷。

架構選擇不只影響速度,也影響你會踩到哪些坑。


實際算一次:把 Day 3 的式子套到兩顆模型上

現在來做今天最有價值的一件事——把換算過程完整寫出來,讓你能換到自己的機器上算。

Day 3 那條式子再貼一次:

理論上限 tok/s ≈ 記憶體頻寬 ÷ 每個 token 需要讀取的權重量

我的分子固定是 273 GB/s(GB10 的 LPDDR5X 統一記憶體頻寬)。

量化格式是 NVFP4,每個參數約 0.5 byte。

情境 A:26B MoE,只讀活躍參數

活躍權重 = 3.8B × 0.5 byte ≈ 1.9 GB
理論上限 = 273 GB/s ÷ 1.9 GB ≈ 143 tok/s

情境 B:如果同一顆模型是 Dense(假想對照組)

權重總量 = 25.2B × 0.5 byte = 12.6 GB
理論上限 = 273 GB/s ÷ 12.6 GB ≈ 21.7 tok/s

情境 C:31B Dense(真正的候選對手)

權重總量 = 30.7B × 0.5 byte ≈ 15.35 GB
理論上限 = 273 GB/s ÷ 15.35 GB ≈ 17.8 tok/s

放在一起看

情境 每 token 讀取權重 理論上限 tok/s 屬性
A:26B MoE(活躍 3.8B) 1.9 GB 143 理論推算
實測(26B MoE,長輸出收斂值) — 48.5 實測
B:26B 假設為 Dense 12.6 GB 21.7 理論推算
C:31B Dense 15.35 GB 17.8 理論推算

三個觀察:

① 實測 48.5 是「26B 當 Dense 跑」上限的 2.2 倍。 這是 MoE 的稀疏讀取真的有效的證據——它確實沒在讀全部權重。

② 實測 48.5 只有 MoE 理論上限的 34%。 中間那 66% 的損耗,Day 3 已經拆過可能的來源:dense 的 attention 層、KV cache 的來回搬運、router 每步的開銷、kernel 效率本身。我沒有拆到更細,所以這條式子的正確用法是算天花板,不是算預期值。

③ 換到 31B Dense,理論上限只有 17.8。 對照現在實測的 48.5,慢 2.7 倍。而且注意,17.8 是 Dense 的天花板;如果它也有跟 MoE 類似比例的實作損耗,實際會更低。

💡Tip: 這張表最值得你帶走的不是任何一個數字,是**「理論值只能跟理論值比」**這個紀律。我上面拿「實測 48.5」去跟「理論 17.8」比出 2.7 倍,嚴格講是不對稱的比較——正確的說法是「48.5 的實測 vs 17.8 的天花板,代表 Dense 就算調到滿也追不上」。這樣講才站得住。 Day 10 我會把這個不對稱再處理一次,因為標題那組數字就是踩在這條線上。


那 Dense 的品質優勢呢?

你可能會想:慢 2.7 倍換來更準,說不定划算?

這個想法完全合理,而且我不打算在今天用嘴巴反駁它。

但我要先把成本結構講清楚,因為這決定了明天的實驗要怎麼設計:

26B MoE 31B Dense
40 頁年報單線跑完(按理論上限推) — —
40 頁年報單線跑完(按 48.5 實測推) 約 10 分鐘 —
40 頁年報單線跑完(按 17.8 天花板推) — 約 27 分鐘以上
準確率改善 基準 未知

看最後一行。

我為了一個「未知」的改善,要先付出一個「確定」的 2.7 倍成本。

這在工程上是一筆很糟的交易——除非你能把它縮到只在真正需要的地方付。

而「哪裡是真正需要的地方」,就是明天要測的東西。

(這段的邏輯我在 Day 5 的 Phase 1 收斂表裡已經先寫過一次:第 ① 條失敗模式「圖例清單頁只有 76.2%」的直覺解法是換大模型,硬體給的答案是 ❌。今天只是把那個 ❌ 的理由攤開到架構層。)


任務類型 × 架構:一張可以照抄的對應表

這是今天最實用的一節。我把「什麼任務適合什麼架構」整理成判斷依據——注意這張表的所有判斷都建立在你的硬體上,換一台機器結論會變:

任務特徵 偏向 理由
長輸出、要串流給人看 MoE decode 次數多,活躍參數直接決定體感速度
短輸出、高精度(分類、抽單一欄位、是非判斷) Dense 可接受 token 數少,慢一點吃得起
批次離線處理 看 batch 開不開得起來 吞吐由 batch 決定,不是由單序列速度決定(Day 5)
機器頻寬 > 1 TB/s Dense 的劣勢變小 分母一樣、分子大 6 倍,21.7 會變成 140+
記憶體小於總參數 只能選更小的模型 MoE 不打折,裝不下就是裝不下
需要多個模型同時在線 總參數要一起算 統一記憶體是共享的,會互相排擠(Day 3)

倒數第三行值得多講一句:如果你有 H100(3,350 GB/s),今天這整篇的結論可能會反過來。

H100 跑 31B Dense:3350 ÷ 15.35 ≈ 218 tok/s

218 tok/s 的 Dense,比我這台 48.5 tok/s 的 MoE 快 4.5 倍。在那台機器上,「用 Dense 換準確率」根本不是一個需要猶豫的決定。

所以「選 MoE」不是一個普世正確的答案,它是我這台機器上的答案。 這也是為什麼我每次都把換算式寫出來,而不是只給你結論。

💡Tip: 這裡有個很常見的閱讀陷阱——你在網路上看到的模型選型建議,絕大多數沒有講作者的硬體。「XX 模型比 YY 好」這種句子,少了硬體前提就等於沒講。 這跟 Day 4 講「看到量化準確率數字要先問三件事」是完全同一個毛病:脫離條件的結論不能遷移。


換算到你自己的機器:一個我沒預期到的規律

上面那個 H100 的例子讓我想把三台機器排在一起算一次。分母沿用前面兩個情境(MoE 活躍權重 1.9 GB、31B Dense 15.35 GB),分子換成各自的頻寬。

三台機器的頻寬數字都出自 Day 3 那張對照表:

裝置 記憶體頻寬 26B MoE 理論 tok/s 31B Dense 理論 tok/s 倍差
DGX Spark(GB10) 273 GB/s 143 17.8 8.1x
RTX 5090 1,792 GB/s 943 116.7 8.1x
H100 SXM5 3,350 GB/s 1,763 218.2 8.1x

(全部是理論推算,不是實測。而且 tok/s 上千那幾格你不要當真——那個數量級早就撞到別的瓶頸了,列出來只是為了讓你看清楚倍率。)

看最右邊那一欄。

8.1 倍。三台都一樣。

想想也是理所當然的——倍率就是 15.35 ÷ 1.9,跟分子完全無關。頻寬換了,分子分母同時被放大,比值不動。

但這個「理所當然」推出來的結論,我覺得非常反直覺:

架構帶來的倍率差距,在每台機器上都一樣。真正會變的是「絕對值有沒有跨過可用門檻」。

在 GB10 上,Dense 的 17.8 掉進了「你會盯著螢幕嘆氣」的區間
在 H100 上,Dense 的 218 還穩穩待在「完全夠用」的區間

倍率相同,結論相反。

所以選型的問題從來不是「哪個架構比較快」——那個答案在所有機器上都一樣,MoE 快 8.1 倍,講完了。

問題是:在你這台機器上,慢的那個有沒有慢到出局。

我這台有。所以我選 MoE。

順帶一提,RTX 5090 那一行還藏著另一件事:它的頻寬是我的 6.6 倍,但記憶體只有 32GB。26B MoE 的 12.6 GB 權重裝得下,31B Dense 的 15.35 GB 也裝得下——但扣掉權重之後剩給 KV cache 的空間,會讓你在長 context 上先撞到另一堵牆(Day 5 算過,單一 64K 序列的 KV cache 就要約 4.9 GiB)。

快的機器有快的機器的坑。 這就是為什麼我堅持把兩個參數量分開看:一個管速度,一個管裝不裝得下,而你要同時過這兩關。


一個我必須誠實標的推估:batch 之下 MoE 還有優勢嗎?

Day 5 有個數字我當時就覺得需要回來處理:併發 4 的總吞吐是 156.9 tok/s,超過了單序列理論上限 143。

當時的解釋是「權重搬一次服務 4 個序列,把頻寬成本攤掉了」。這個解釋對 Dense 模型完全成立。

但 MoE 有一個 Dense 沒有的變數:不同的 token 會被 router 送到不同的 expert。

推到極端:如果 batch 裡的 8 個 token 剛好被路由到 8 組完全不重疊的 expert,那這一個 batch step 要搬的權重就不是 1.9 GB,而是接近這些 expert 的聯集。batch 越大,聯集越大,最壞情況下所有 expert 都會被點到一次。

那時候 MoE 就退化成 Dense 了。

batch 大小 每 step 搬的權重(推估) MoE 相對 Dense 的優勢
1 ≈ 活躍參數 最大
小 batch 活躍參數 ~ 部分聯集 仍然明顯
大 batch 逼近總參數 趨近消失

但我要標清楚:這張表整張都是「依 MoE 通則推估」,不是我的實測。

我的實測只做到併發 4(Day 5 的 1 / 2 / 4),而且在那個範圍內看不出任何退化跡象——總吞吐從 48.9 一路漲到 156.9,接近線性。所以「大 batch 會讓 MoE 優勢消失」這句話,在我手上沒有證據,只有理由。

那它為什麼還值得寫?

因為它會影響架構決策的方向:

  • 我的場景是小 batch + 長輸出(一頁一頁 OCR,每頁吐幾百個 token)→ MoE 的優勢在這裡最大
  • 如果我的場景是大 batch 離線批次(一次塞 64 個請求進去慢慢跑)→ 這個優勢可能會縮,我得重新量

而 Day 5 已經講過,大 batch 在我這台上本來就開不起來——KV cache 會先吃光記憶體。

所以這條推估對我目前的架構沒有影響,但我把它記下來,因為條件一變它就會回來咬人。


所以,為什麼這個專案選 26B MoE?

把上面全部收斂成四個理由:

① 頻寬是硬瓶頸,而 MoE 直接打在瓶頸上

273 GB/s 是物理限制。MoE 把「每 token 要搬的權重」從 12.6 GB 壓到 1.9 GB,這是唯一一個能在不換硬體的前提下改善分母的辦法(另一個是量化,那是改分子的單價,Day 4 講過)。

② 128GB 統一記憶體讓 MoE 的缺點消失

MoE 最大的缺點是「總參數全部要常駐」。但我有 128GB,25.2B 的 NVFP4 權重只佔 12.6 GB。這台機器的記憶體多到讓 MoE 的代價變成零。

反過來說:GB10 這種「容量大、頻寬小」的硬體,跟 MoE 是天作之合。 它剛好是 MoE 要的那種機器。

③ OCR 是長輸出任務

回頭看 Day 2 的實測,一頁財報的 completion tokens 落在 141 到 737 之間。這是典型的長輸出——decode 次數多,正是 MoE 的主場。如果我做的是「判斷這頁是不是表格」這種一個字就講完的任務,Dense 的劣勢根本顯現不出來。

④ 它「夠準」,不是「最準」

Day 2 的實測:純文字頁覆蓋率 99.4%、有框線的財務表 98% 以上。這個水準不是完美,但它讓我有本錢把架構的重點放在驗證與修正,而不是繼續追模型本身的準確率。

回到 Day 1 那句話:

Agents need feedback loops, not perfect prompts.

我今天想補一個對仗版本:

也不是 perfect models。

那為什麼不乾脆選更小的?

這題我被問過,而且它比「為什麼不選更大的」更值得算一次。

我手上還有另一個實際跑過的候選——Day 4 做量化實驗時用的 gemma-4-12B-it-NVFP4A16。12B 顯然比 26B 小得多,直覺上應該快很多。

它的架構是 Dense 還是 MoE,我沒有查證。 但我們可以把兩種可能都算一遍:

假設 每 token 讀取權重 理論上限 tok/s
12B 是 Dense(12B × 0.5 byte) 6.0 GB 45.5
12B 是 MoE(活躍參數未知) 未知 未知

看第一行那個數字。

45.5。

而我的 26B MoE,實測就有 48.5。

如果 12B 真的是 Dense,那結論是:一顆參數量少一半的模型,理論天花板還比我現在這顆的實測值低。

這就是 MoE 這件事最違反直覺的地方——「小模型比較快」這個直覺,只在同一種架構內部成立。 跨架構比較的時候,參數量本身沒有意義,你要比的是活躍參數。

(再標一次:45.5 是理論推算,而且建立在「12B 是 Dense」這個未經查證的假設上。如果它其實也是 MoE,這個算式整個不成立。我把推導過程寫出來就是為了讓你能在假設變了的時候自己重算。)


誠實區:Gemma 4 的架構細節我查證到哪裡

這節是我覺得整篇最重要的一節。

因為你如果去搜「Gemma 4 MoE 架構」,很容易找到一堆講得非常具體的文章——幾個 expert、top-k 選幾個、每層長怎樣。我不打算加入那個行列,因為我沒有查證。

我把「我有存檔可以指」跟「我沒有」分成兩欄:

項目 值 屬性
服務中的模型 id gemma-4-26b 端點存檔(/v1/models)
模型路徑 /models/gemma4 端點存檔
max_model_len 131072 端點存檔
vLLM 版本 0.19.1.dev6+g6d4a8e6d2 端點存檔(/version)
max_position_embeddings 32768 config.json(Day 3 引用)
量化格式 NVFP4(ModelOpt export) 我自己的部署設定
總參數 / 活躍參數 25.2B / 3.8B 沿用 Day 3 的換算基數
expert 總數 — ❌ 未查證
每 token 選幾個 expert(top-k) — ❌ 未查證
是否每一層 FFN 都是 MoE — ❌ 未查證
有沒有 shared expert(常駐專家) — ❌ 未查證
視覺塔是 dense 還是 MoE — ❌ 未查證
31B Dense 的一手規格出處 30.7B(Day 5 的換算基數) ⚠️ 一手出處未查證,沿用前篇

那為什麼上面那些換算還能成立?

因為換算只需要「活躍參數」這一個數字,不需要知道它是怎麼分配到幾個 expert 上的。

273 ÷ (3.8 × 0.5) 這個算式裡,沒有任何一個變數是 expert 數量。

換句話說:我不知道的那些細節,剛好不影響我要做的決定。 這件事本身就值得記一下——很多時候「查不到」不是障礙,你只需要確認它有沒有出現在你的算式裡。

💡Tip: 這節的做法你可以直接抄去用:寫技術判斷的時候,先畫一條線,把「我有存檔可以指的」跟「我聽說的」分開。 然後檢查你的結論用到了哪一欄。如果結論踩在右邊那欄,你要嘛去查證,要嘛把結論降級成推測。我 Day 3 就吃過虧——一個沒記條件的「150 tok/s」差點讓我寫出一整段錯的分析。

我刪掉的那一段

這篇的初稿裡,我原本在這個位置寫了一段「Gemma 4 的 MoE 設計選擇」——講它為什麼這樣切 expert、跟其他 MoE 模型的設計哲學差在哪、在某某 benchmark 上的表現如何。

寫得很順,讀起來也很專業。然後我回頭找出處,一條都找不到。

那段東西不是我查來的,是我從別的 MoE 模型的常見設計「推」出來的,然後在寫的過程中,那個「推」字不知道什麼時候自己掉了。

這件事跟 Day 3 那個「150 tok/s」是同一種病,只是方向相反:Day 3 是把自己的舊筆記當成一手資料,這次是把通則當成特定事實。

所以我把整段刪掉,換成上面那張表。

💡Tip: 我後來給自己定了一個很機械的檢查:寫完之後,把文章裡每一個「具體規格數字」圈起來,逐個問「我現在能指出它存在於哪個檔案/哪一頁嗎」。 指不出來的,要嘛降級成「推估」,要嘛刪掉。這個檢查很無聊,但它抓到的東西通常都是最會讓你丟臉的那幾句。Day 5 那個 speculative decoding 的段落,我就是靠這個檢查才發現自己把「官方清單沒列」寫成了「不存在」。

另外補一句方法論上的:上面所有標「通則」的敘述(MoE 品質略遜於同等總參數的 Dense、attention 層通常是 dense 的、router 有固定開銷),我的定位是依 MoE 架構通則推估,不是 Gemma 4 的實測特性。如果你要拿去做重要決定,請自己再驗一次。


兩種架構的載入配置差在哪

最後給一點可以動手的東西。這是我實際在跑的那組參數的骨架,以及如果要換成 Dense 要動哪些:

# 現況:26B MoE(NVFP4 / safetensors / vLLM)
vllm serve /models/gemma4 \
  --served-model-name gemma-4-26b \
  --port 8004 \
  --max-model-len 131072 \
  --gpu-memory-utilization 0.6
  # 注意這裡「沒有」的東西比有的更重要:
  #   沒有 --quantization        → checkpoint 自己宣告了,CLI 再指定會衝突(Day 4)
  #   沒有 --kv-cache-memory-bytes → 統一記憶體上自設上限是給自己挖坑(Day 3)
  #   沒有 --moe-backend          → 除非你確定它對得上 checkpoint 格式,否則一律先刪

換成 Dense 的話,要動的是這三類:

要改的 為什麼
--max-model-len Dense 模型的原生 context 不一定一樣,要重查
--gpu-memory-utilization 權重從 12.6 GB 變 15.35 GB,KV cache 的可用空間跟著變
所有 MoE 專屬 flag 整組刪掉 Day 4 的「③ 禁止繼承」那一類——從舊設定複製貼上最容易死在這裡

💡Tip: 最後這條再強調一次,因為它是換模型時最常見的死法:你不會意識到那行 MoE 專屬參數還留在設定檔裡。 它不會報錯,它會讓你在錯誤的方向 debug 一整晚。換模型的正確起手式是先刪到最乾淨,再一行一行加回來。


選型的六個步驟:一份可以照做的清單

把今天全部的東西收成一個可以執行的順序。這是我自己實際走過的流程,不是理論:

① 先量你的頻寬,不是算力

規格表上最大的那個數字通常是算力(TFLOPS、PFLOPS),而那個數字在 decode 階段幾乎用不到。你要找的是 memory bandwidth。找不到的話用「記憶體類型 × 位元寬 × 時脈」反推也行,抓個量級就夠。

② 對每個候選模型算兩個數

裝得下嗎? = 總參數 × 每參數 byte 數   (要小於你的可用記憶體,而且要留空間給 KV cache)
跑多快?   = 記憶體頻寬 ÷ (活躍參數 × 每參數 byte 數)

Dense 模型的兩個數用的是同一個參數量,MoE 才會分岔。

這件事我後來寫成一個十行的小函式,換模型的時候直接餵數字進去,省得每次都手算錯:

BYTES_PER_PARAM = {"bf16": 2.0, "fp8": 1.0, "int8": 1.0, "nvfp4": 0.5}

def sizing(total_b, active_b, quant, bandwidth_gbs, mem_gb):
    """total_b / active_b 單位是 B(十億參數);Dense 就把兩個填一樣。"""
    bpp = BYTES_PER_PARAM[quant]
    weights_gb = total_b * bpp          # 常駐記憶體:看總參數
    read_gb    = active_b * bpp         # 每 token 搬運量:看活躍參數
    return {
        "weights_gb": round(weights_gb, 2),
        "fits": weights_gb < mem_gb,    # 注意:這裡還沒扣 KV cache
        "ceiling_tok_s": round(bandwidth_gbs / read_gb, 1),
    }

# 我的兩個候選,同一台 GB10(273 GB/s、128GB 統一記憶體)
print(sizing(25.2, 3.8,  "nvfp4", 273, 128))   # 26B MoE
print(sizing(30.7, 30.7, "nvfp4", 273, 128))   # 31B Dense

輸出就是前面那張表的 12.6 GB / 143 tok/s 與 15.35 GB / 17.8 tok/s。

fits 那行我刻意留了一個註解——它只比對權重,沒有扣 KV cache。實際判斷「裝不裝得下」,你還要按 Day 5 的式子把 batch size × context 長度 × KV cache 單價 加進去。這個函式回答的是「權重層級的門票」,不是「這組設定真的跑得起來」。

③ 把「跑多快」的天花板打個折當預期值

我這台的實測是天花板的 34%(48.5 / 143)。

但我要標清楚:34% 是我這一台、這一顆模型、這一個量化格式、這一版 vLLM 的單點觀察,不是通則。 你換任何一個條件都可能不一樣。我列出來是給你一個「大概會掉到什麼量級」的心理準備,不是讓你拿去當公式用。

④ 乘上你的典型輸出長度,換成「一件事要幾秒」

這步最重要,因為 tok/s 這個單位對人類沒有意義。

我的換算是:一頁財報的 completion tokens 落在 141–737(Day 2 實測),取中間值約 400,除以 48.5,大概 8 秒一頁。40 頁就是 5–6 分鐘。

⑤ 問「這個秒數能不能接受」——不能就換架構,不是調參

這是 Day 3 那個 💡Tip 的完整版。如果你算出天花板 143、實測 48,那中間還有調校空間;但如果你算出來的天花板就只有 17.8,那調參是浪費時間,只剩換架構或換量化兩條路。

⑥ 最後才看準確率

我知道這個順序看起來很怪——準確率不是最重要的嗎?

是。但準確率是在可用的候選裡挑最好的。一顆準到爆但要跑 27 分鐘的模型,它根本不在候選名單上,你不需要知道它有多準。

先用硬體刷掉不可能的,再用準確率排序剩下的。 反過來做,你會花很多時間評測一堆你根本用不起的模型。


小結:架構選擇是硬體的函數

今天講的東西可以壓縮成一條式子跟一句話。

式子:

decode 天花板 = 記憶體頻寬 ÷ (活躍參數 × 每參數 byte 數)

話:

總參數決定你裝不裝得下,活躍參數決定你跑多快。在頻寬受限的機器上,後者才是你能動的那個變數。

然後是今天的幾條結論:

  • MoE 省的是頻寬,不是容量——25.2B 的權重還是得全部常駐
  • 在 GB10 上,26B MoE 的實測 48.5 tok/s 是「同顆模型當 Dense 跑」的 2.2 倍,是 31B Dense 理論天花板(17.8)的 2.7 倍以上
  • 這個結論綁死在 273 GB/s 上——換到 H100 會整個反過來
  • Gemma 4 的 expert 細節我沒有查證,但那些細節剛好不在我的算式裡
  • 31B Dense 沒被淘汰,它被降級成「只在特定區塊使用」的候選

最後一條就是明天的題目。

因為今天整篇都在講「平均而言 MoE 比較划算」,但 Day 2 已經告訴我們一件事:這份文件不是均質的。純文字頁 99.4%,圖例清單頁 76.2%,中間差了 23 個百分點。

既然頁面不均質,憑什麼用同一顆模型跑完全部?

明天我們把純文字區跟表格區拆開來量,看看那個「50 tok/s 與 7 tok/s」的取捨到底長什麼樣子——而且我會先講清楚,那兩個數字哪一個是實測、哪一個是推算。

明天見 👋


上一篇
Day 8 - 繁中挑戰總結:這些問題怎麼倒推出系統設計
下一篇
Day 10 - 純文字區與表格區實測:50 tok/s 與 7 tok/s 的取捨
系列文
從 LLM 到 Harness: 打造隱私與可信任的繁中進階 OCR Agent 共 12 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言